# coding=utf-8
"""
作者：dnscmd@qq.com
创建时间：2024/12/16 14:18
描述：将A目录中的文件同步到B目录中
"""
import glob
import hashlib
import os.path
import subprocess
import time
from os import path

from tqdm import tqdm


def dir_diff(dir1: str, dir2: str):
    """
    比较两个文件夹内文件的差异
    :param dir1: 文件夹1
    :param dir2: 文件2
    """
    if not os.path.isdir(dir1):
        print(f'{dir1} not exists')
        return
    if not os.path.isdir(dir2):
        print(f'{dir2} not exists')
        return

    files1 = {os.path.basename(v) for v in glob.glob(path.join(dir1, "*"))}
    files2 = {os.path.basename(v) for v in glob.glob(path.join(dir2, "*"))}

    _1_2 = list(files1 - files2)
    _2_1 = list(files2 - files1)

    _1_2.sort()
    _2_1.sort()

    print(f"in {dir1} not in {dir2}: ", _1_2)
    print(f"in {dir2} not in {dir1}: ", _2_1)


def file_to_hash(fname: str, hash_algo='sha256'):
    """
    计算文件的哈希值
    :param fname:文件名
    :param hash_algo  使用的hash类型
    :return: 文件哈希值
    """
    hash_func = getattr(hashlib, hash_algo)()
    with open(fname, 'rb') as f:
        while chunk := f.read(8192):  # 逐块读取文件
            hash_func.update(chunk)
    return hash_func.hexdigest()


class Node:
    def __init__(self, fname: str):
        self.fname = fname


def backup_files_to_target_dir(source_dir: str, bak_dir: str):
    """
    将源文件夹内的文件增量同步到备份文件夹内
    :param source_dir: 源文件夹
    :param bak_dir: 备份文件夹
    """
    source_files_dic, bak_files_dic = {}, {}

    print('索引源目录：')
    fls = [(root, fnames) for root, _, fnames in os.walk(source_dir) if '.git' not in root]
    for root, fnames in tqdm(fls, total=len(fls)):
        for fname in fnames:
            if fname.startswith(r'~$'):  # 不更新word临时文件
                continue
            fname = os.path.join(root, fname)
            source_files_dic[file_to_hash(fname)] = fname

    time.sleep(0.1)
    print('\n索引备份目录：')
    fls = [(root, fnames) for root, _, fnames in os.walk(bak_dir)]
    for root, fnames in tqdm(fls, total=len(fls)):
        for fname in fnames:
            fname = os.path.join(root, fname)
            bak_files_dic[file_to_hash(fname)] = fname

    # 计算存在差异的文件
    change_file_hash = set(source_files_dic.keys()) - set(bak_files_dic.keys())
    if not change_file_hash:
        print("【备份文件】：【成功：不需要更新，都是最新的！】")
        return

    for hs in tqdm(change_file_hash, total=len(change_file_hash)):
        source_fname = source_files_dic[hs]
        target_fname = bak_dir + source_fname.replace(source_dir, '')
        target_dir = os.path.dirname(target_fname)

        if not os.path.isdir(target_dir):
            subprocess.run(f'cmd.exe /C mkdir "{target_dir}"')

        command = f'copy /Y "{source_fname}" "{target_fname}"'  # 使用系统命令执行文件复制，/Y 参数表示覆盖已有文件
        subprocess.run(command, shell=True, check=True)
        print(f"【{os.path.basename(source_fname)}】 {os.path.dirname(source_fname)} -> {target_dir}")
    print(f"【备份文件】：【成功：一共更新{len(change_file_hash)}个文件，完成！】")


if __name__ == '__main__':
    # dir_diff(r'D:\works\01 海南\00 生产项目准入及预算标准（2022年版）', r'D:\works\00 生产项目准入及预算标准（2022年版）')
    backup_files_to_target_dir(r'C:\dns\works', r'e:')
    time.sleep(0.1)
    input("press Enter to exit")
